package com.ethank.config;

import com.alibaba.fastjson2.JSON;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

//
// import com.alibaba.fastjson2.JSON;
// import org.aspectj.lang.JoinPoint;
// import org.aspectj.lang.ProceedingJoinPoint;
// import org.aspectj.lang.annotation.Around;
// import org.aspectj.lang.annotation.Aspect;
// import org.aspectj.lang.annotation.Before;
// import org.aspectj.lang.annotation.Pointcut;
// import org.aspectj.lang.reflect.MethodSignature;
// import org.slf4j.Logger;
// import org.slf4j.LoggerFactory;
// import org.springframework.stereotype.Component;
//
// import java.util.Arrays;
// import java.util.UUID;
//
// /**
//  * @author tf
//  * @date 2024-07-22
//  * @Description
//  */
@Aspect
@Component
public class RequestLogAspect {
//
//
//     private static final Logger PARAM_LOG = LoggerFactory.getLogger(RequestLogAspect.class);
    private static final Logger log = LoggerFactory.getLogger(RequestLogAspect.class);
//
//
//     /**
//      * 定义切点： execution ,with,target等，可以参考官方文档
//      * https://docs.spring.io/spring-framework/reference/core/aop/ataspectj/pointcuts.html
//      */
//     @Pointcut(value = "execution(public * com.ethank.controller.ocr..*(..))")
//     public void cut() {
//     }
//
//     /**
//      * 使用环绕通知：可以拿到请求前和请求后的参数，同时打印
//      *
//      * @param joinPoint 连接点
//      * @return
//      */
//     @Around(value = "cut()")
//     public Object printWebParam(ProceedingJoinPoint joinPoint) throws Throwable {
//         // 可以加入接口记录时间，方法进入的时间
//         long start = System.currentTimeMillis();
//
//         // 获取连接点方法签名，可以从中解析得到关于该方法的许多信息
//         MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
//
//         // 方法所在类名称
//         String declaringTypeName = methodSignature.getDeclaringTypeName();
//         // 方法名
//         String methodName = methodSignature.getMethod().getName();
//
//         // 生成唯一的交易编码，便于观察出参和入参
//         String uuid = UUID.randomUUID().toString();
//
//         // 获取参数
//         Object[] args = joinPoint.getArgs();
//         String jsonString = JSON.toJSONString(args);
//         // 判断是否开启打印，打印请求信息
//         if (PARAM_LOG.isInfoEnabled()) {
//             PARAM_LOG.info("TRACE:{} , 请求服务{} - 请求方法{}, 请求参数： {}", uuid, declaringTypeName, methodName, jsonString);
//         }
//
//
//         Object result = null;
//         try {
//             // 执行代理类的实现逻辑
//             result = joinPoint.proceed();
//         } catch (Throwable throwable) {
//             if (PARAM_LOG.isErrorEnabled()) {
//                 PARAM_LOG.error("TRACE:{} , 请求服务{} - 请求方法{}, 发生异常了，原因是： {}", uuid, declaringTypeName, methodName, throwable.getMessage(), throwable);
//             }
//             throw throwable;
//         }
//         // 方法结束的时间
//         long end = System.currentTimeMillis();
//         // 判断是否开启打印，打印结果信息
//         if (PARAM_LOG.isInfoEnabled()) {
//             PARAM_LOG.info("TRACE:{} , 请求服务{} - 请求方法{} , 请求耗时 ： {} ms , 请求结果： {}", uuid, declaringTypeName, methodName, (end - start), jsonString);
//         }
//
//         return result;
//     }
//
//
   /**
   * @Description: 切点
   * @Param: []
   * @return: void
   * @Author: tf
   * @Date: 2024-07-23
   */
    @Pointcut("execution(public * com.ethank.controller.ocr..*(..))")
    public void log() {
    }
    /**
     * @Description: 请求
     * @Param: [joinPoint]
     * @return: void
     * @Author: tf
     * @Date: 2024-07-23
     */
    @Before("log()")
    public void doBefore(JoinPoint joinPoint) {
        // 主类
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes != null){
            HttpServletRequest request = attributes.getRequest();
            // url 路径
            log.info("request={}", request.getRequestURL() + " | method=" + request.getMethod() + " | ip=" + request.getRemoteAddr());
            // 类方法
            log.info("method={}", joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
            // 参数
            log.info("params={}", Arrays.toString(joinPoint.getArgs()));
        }
    }
     /**
     * @Description:  返回处理
     * @Param: [result]
     * @return: void
     * @Author: tf
     * @Date: 2024-07-23
     */
    @AfterReturning(returning = "result", pointcut = "log()")
    public void doAfterReturning(Object result) {

        log.info("return={}", JSON.toJSON(result));
    }


}